#include "sem_posix.h"
#include <semaphore.h>
#include <errno.h>


CSem::CSem()
    :m_sem(NULL)
{}

CSem::~CSem()
{
    if (m_sem != NULL)
        sem_close(m_sem);
}

bool CSem::open(const string& filename,unsigned int initvalue,
        int flags,int mode)
{
    if (filename.empty())
        return false;
    
    m_name = filename;

    m_sem = sem_open(filename.c_str(),flags,mode,initvalue);
    
    if (m_sem == SEM_FAILED)
    {
        int tmp = flags & SEM_CREAT;
        if (isOpened())
        {
            if ( tmp == SEM_CREAT)
                flags -= SEM_CREAT;
        }
        m_sem = sem_open(filename.c_str(),flags,mode,initvalue);
    }
    
    return m_sem != SEM_FAILED;
}

bool CSem::isOpened()
{
    if (m_name.empty())
        return false;

    sem_t* sem = sem_open(m_name.c_str(),
            SEM_CREAT|SEM_EXECL,
            USER_R|USER_W|OTHER_R,
            1);
    
    if (sem == SEM_FAILED && errno == EEXIST)
    {
        return true;
    }
    
    return false;
}

bool CSem::lock()
{
    int ret = 0;
    if (m_sem != NULL)
    {
        ret = sem_wait(m_sem);
    }
    return ret == 0;
}

bool CSem::trylock()
{
    int ret = 0;
    if (m_sem != NULL)
    {
        ret = sem_trywait(m_sem);
    }
    return ret == 0;
}

bool CSem::timelock(unsigned int second)
{
    int ret = 0;
    if (m_sem != NULL)
    {
        struct timespec ts;
        ts.tv_sec = second;
        ts.tv_nsec = 0;
        ret = sem_timedwait(m_sem,&ts);
    }
    return ret == 0;
}

bool CSem::unlock()
{
    int ret = 0;
    if (m_sem != NULL)
    {
        ret = sem_post(m_sem);
    }
    return ret == 0;
}

bool CSem::unlink()
{
    int ret = 0;
    if (m_sem != NULL)
    {
        sem_unlink(m_name.c_str());
    }
    return ret == 0;
}









